﻿using AuthCenter.API.Application.Command.Account;
using AuthCenter.API.DTOs;
using AuthCenter.Common;
using AuthCenter.Domain;
using AuthCenter.Domain.Account;
using AuthCenter.Domain.Menu;
using AuthCenter.ErrorCode;
using AuthCenter.Intertructrue.Interface;
using MD5Hash;
using MediatR;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Text;

namespace AuthCenter.API.Application.Handler.Account
{
    public class LoginHandler : IRequestHandler<LoginCommand, APIResult<LoginDTO>>
    {
        private readonly IBaseRepository<AccountModel> accountRepo;
        private readonly IBaseRepository<AccountRoleModel> accountroleRepo;
        private readonly IBaseRepository<RoleModel> roleRepo;
        private readonly IBaseRepository<RoleMenuModel> rolemenuRepo;
        private readonly IBaseRepository<MenuModel> menuRepo;
        private readonly IConfiguration configuration;

        public LoginHandler(IBaseRepository<AccountModel> accountRepo,
                            IBaseRepository<AccountRoleModel> accountroleRepo,
                            IBaseRepository<RoleModel> roleRepo,
                            IBaseRepository<RoleMenuModel> rolemenuRepo,
                            IBaseRepository<MenuModel> menuRepo,
                            IConfiguration configuration
                            )
        {
            this.accountRepo = accountRepo;
            this.accountroleRepo = accountroleRepo;
            this.roleRepo = roleRepo;
            this.rolemenuRepo = rolemenuRepo;
            this.menuRepo = menuRepo;
            this.configuration = configuration;
        }
        public Task<APIResult<LoginDTO>> Handle(LoginCommand request, CancellationToken cancellationToken)
        {
            APIResult<LoginDTO> result = new APIResult<LoginDTO>();
            JwtTools jwtTools = new JwtTools();
            var res = accountRepo.GetAll().FirstOrDefault(x=>x.Name == request.Name);
            if (res == null)
            {
                result.Message = "用户名不存在";
                result.Code = APIEnum.Fail;
                return Task.FromResult(result);
            }
            if(res.PassWord != request.Password.GetMD5())
            {
                result.Message = "密码错误";
                result.Code = APIEnum.Fail;
                return Task.FromResult(result);
            }
            LoginDTO loginDTO = new LoginDTO()
            {
                Name = res.Name,
                token = jwtTools.JwtNewString(configuration, res.Id.ToString())
            };
            var accountrole = accountroleRepo.GetAll().Where(x => x.AccountId == res.Id).ToList();
            var roleMenuIds = new List<long>();
            var allMenus = new List<MenuTreeDTO>();
            foreach (var item in accountrole)
            {
                var role = roleRepo.GetAll().FirstOrDefault(x => x.Id == item.RoleId);
                if (role == null)
                {
                    continue;
                }
                loginDTO.RoleName.Add(role.RoleName);
                var rolemenu = rolemenuRepo.GetAll().Where(x => x.RoleId == item.RoleId).ToList();
                foreach (var items in rolemenu)
                {
                    if (!roleMenuIds.Contains(items.MenuId))
                    {
                        roleMenuIds.Add(items.MenuId);
                        var menu = menuRepo.GetAll().FirstOrDefault(x => x.Id == items.MenuId);
                        if (menu == null)
                        {
                            continue;
                        }
                        var menuTreeDTO = new MenuTreeDTO()
                        {
                            Id = items.MenuId,
                            MenuName = menu.MenuName,
                            Url = menu.Url,
                            ParentId = menu.ParentId,
                            Children = new List<MenuTreeDTO>()
                        };
                        allMenus.Add(menuTreeDTO);
                    }
                }
            }
            loginDTO.RoleName = loginDTO.RoleName.Distinct().ToList();
            var roleRelatedMenus = allMenus.Where(m => roleMenuIds.Contains(m.Id)).ToList();
            var rootMenus = roleRelatedMenus.Where(m => m.ParentId == null || m.ParentId == 0).ToList(); 
            foreach (var rootMenu in rootMenus)
            {
                BuildMenuTree(rootMenu, roleRelatedMenus);
            }
            loginDTO.MenuTree = rootMenus;


            var department = accountRepo.GetAll().FirstOrDefault(x => x.Id == res.Id).Department;
            var account = accountRepo.GetAll().Where(x => x.Department == department).ToList();
            var r = "";
            foreach (var item in account)
            {
                var head = accountroleRepo.GetAll().FirstOrDefault(x => x.AccountId == item.Id);
                if (head == null)
                {
                    continue;
                }
                var accounthead = accountRepo.GetAll().FirstOrDefault(x => x.Id == head.AccountId&&x.Department==department);
                if (accounthead != null)
                {
                    r = accounthead.Name;
                    break;
                }
            }
            loginDTO.Department = department;
            loginDTO.DepartmentHead = r;
            result.Message = "登录成功";
            result.Code = APIEnum.Ok;
            result.Data = loginDTO;
            return Task.FromResult(result);
        }
        public void BuildMenuTree(MenuTreeDTO parentMenu, List<MenuTreeDTO> allMenus)
        {
            var childMenus = allMenus.Where(m => m.ParentId == parentMenu.Id).ToList();
            parentMenu.Children = childMenus;
            foreach (var childMenu in childMenus)
            {
                BuildMenuTree(childMenu, allMenus);
            }
        }
    }
}
